from mininet.topo import Topo
from mininet.net import Mininet
from mininet.node import OVSSwitch, Controller, RemoteController, Host
from mininet.cli import CLI
from mininet.log import setLogLevel, info
from mininet.link import TCLink

class MyTopo(Topo):
	"Simple topology example."

	def build(self):
		# Create switches
		s1 = self.addSwitch('s1', dpid='00:00:00:00:00:00:00:01',protocols='OpenFlow13')
		s2 = self.addSwitch('s2', dpid='00:00:00:00:00:00:00:02',protocols='OpenFlow13')
		# Create hosts
		h1 = self.addHost('h1', ip='192.168.0.101/24')
		h2 = self.addHost('h2', ip='192.168.0.102/24')
		h3 = self.addHost('h3', ip='192.168.0.103/24')
		h4 = self.addHost('h4', ip='192.168.0.104/24')
		h5 = self.addHost('h5', ip='192.168.0.105/24')
		h6 = self.addHost('h6', ip='192.168.0.106/24')

		# Add links with specific bandwidth and delay settings
		linkopts0 = dict(bw=300, delay='1ms', loss=0)
		linkopts1 = dict(bw=100, delay='1ms', loss=0)

		self.addLink(h1, s1, cls=TCLink, **linkopts1)
		self.addLink(h2, s1, cls=TCLink, **linkopts1)
		self.addLink(h3, s1, cls=TCLink, **linkopts1)
		self.addLink(h4, s2, cls=TCLink, **linkopts1)
		self.addLink(h5, s2, cls=TCLink, **linkopts1)
		self.addLink(h6, s2, cls=TCLink, **linkopts1)
		self.addLink(s1, s2, cls=TCLink, **linkopts0)
def startMyNet():
	"Create network and run CLI"
	topo = MyTopo()
	net = Mininet(topo=topo, switch=OVSSwitch, controller=None,autoSetMacs=True, autoStaticArp=True)
	c0 = net.addController('c0', controller=Controller)
	net.start()
	# Add OpenFlow rules to the switches

	s1 = net.get('s1')
	s2 = net.get('s2')

	# Rules for s1
	s1.cmd('ovs-ofctl -O OpenFlow13 del-flows s1')
	s1.cmd('ovs-ofctl -O OpenFlow13 add-flow s1 priority=100,in_port=1,actions=push_vlan:0x8100,set_field:4096-\>vlan_vid,output:4')
	s1.cmd('ovs-ofctl -O OpenFlow13 add-flow s1 priority=100,in_port=2,actions=push_vlan:0x8100,set_field:4097-\>vlan_vid,output:4')
	s1.cmd('ovs-ofctl -O OpenFlow13 add-flow s1 priority=100,in_port=3,actions=push_vlan:0x8100,set_field:4098-\>vlan_vid,output:4')
	s1.cmd('ovs-ofctl -O OpenFlow13 add-flow s1 priority=100,dl_vlan=0,actions=pop_vlan,output:1')
	s1.cmd('ovs-ofctl -O OpenFlow13 add-flow s1 priority=100,dl_vlan=1,actions=pop_vlan,output:2')
	s1.cmd('ovs-ofctl -O OpenFlow13 add-flow s1 priority=100,dl_vlan=2,actions=pop_vlan,output:3')

	# Rules for s2
	s2.cmd('ovs-ofctl -O OpenFlow13 del-flows s2')
	s2.cmd('ovs-ofctl -O OpenFlow13 add-flow s2 priority=100,in_port=1,actions=push_vlan:0x8100,set_field:4096-\>vlan_vid,output:4')
	s2.cmd('ovs-ofctl -O OpenFlow13 add-flow s2 priority=100,in_port=2,actions=push_vlan:0x8100,set_field:4097-\>vlan_vid,output:4')
	s2.cmd('ovs-ofctl -O OpenFlow13 add-flow s2 priority=100,in_port=3,actions=push_vlan:0x8100,set_field:4098-\>vlan_vid,output:4')
	s2.cmd('ovs-ofctl -O OpenFlow13 add-flow s2 priority=100,dl_vlan=0,actions=pop_vlan,output:1')
	s2.cmd('ovs-ofctl -O OpenFlow13 add-flow s2 priority=100,dl_vlan=1,actions=pop_vlan,output:2')
	s2.cmd('ovs-ofctl -O OpenFlow13 add-flow s2 priority=100,dl_vlan=2,actions=pop_vlan,output:3')


	CLI(net)
	net.stop()
if __name__ == '__main__':
	setLogLevel('info')
	startMyNet()